/**
  ******************************************************************************
  * @file    rocker.c
  * @author  GEEKROS,  site:www.geekros.com
  ******************************************************************************
*/

#include "rocker.h"

Rocker_Struct Rocker_Data;

/******************************************************************
  * @ 函数名  ： Rocker_Init
  * @ 功能说明： 遥控器初始化，SBUS、UART1作为遥控器专用接口
  * @ 参数    ： int baud_rate 波特率
  * @ 返回值  ： NULL
  *****************************************************************/
void Rocker_Init(int baud_rate)
{
	USART_InitTypeDef USART_InitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	DMA_InitTypeDef DMA_InitStructure;

	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_DMA2,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

	GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_Init(GPIOB, &GPIO_InitStructure);

	USART_DeInit(USART1);
	USART_InitStructure.USART_BaudRate = baud_rate;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_Even;
	USART_InitStructure.USART_Mode = USART_Mode_Rx;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_Init(USART1, &USART_InitStructure);

	USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);
	USART_Cmd(USART1, ENABLE);

	USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE);

	NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream5_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);

	DMA_Cmd(DMA2_Stream5, DISABLE);
	while (
		DMA2_Stream5->CR & DMA_SxCR_EN
	);

	DMA_DeInit(DMA2_Stream5);
	DMA_InitStructure.DMA_Channel = DMA_Channel_4;
	DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(USART1->DR);
	DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)Rocker_Data.buffer;
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
	DMA_InitStructure.DMA_BufferSize = 18;
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
	DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
	DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
	DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
	DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull;
	DMA_InitStructure.DMA_MemoryBurst = DMA_Mode_Normal;
	DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
	DMA_Init(DMA2_Stream5,&DMA_InitStructure);

	DMA_ITConfig(DMA2_Stream5,DMA_IT_TC,ENABLE);
	DMA_Cmd(DMA2_Stream5,ENABLE);
}

/******************************************************************
  * @ 函数名  ： DMA2_Stream5_IRQHandler
  * @ 功能说明： 遥控器的DMA中断函数，处理遥控器信号数据
  * @ 参数    ： NULL
  * @ 返回值  ： NULL
  *****************************************************************/
void DMA2_Stream5_IRQHandler(void)
{
	if(DMA_GetITStatus(DMA2_Stream5, DMA_IT_TCIF5))
	{
		DMA_ClearFlag(DMA2_Stream5, DMA_FLAG_TCIF5);
		DMA_ClearITPendingBit(DMA2_Stream5, DMA_IT_TCIF5);
		
		Rocker_Data.ch0 = (Rocker_Data.buffer[0]| (Rocker_Data.buffer[1] << 8)) & 0x07ff;
		Rocker_Data.ch1 = ((Rocker_Data.buffer[1] >> 3) | (Rocker_Data.buffer[2] << 5)) & 0x07ff;
		Rocker_Data.ch2 = ((Rocker_Data.buffer[2] >> 6) | (Rocker_Data.buffer[3] << 2) | (Rocker_Data.buffer[4] << 10)) & 0x07ff;
		Rocker_Data.ch3 = ((Rocker_Data.buffer[4] >> 1) | (Rocker_Data.buffer[5] << 7)) & 0x07ff;
		Rocker_Data.ch4 = Rocker_Data.buffer[16] | (Rocker_Data.buffer[17] << 8);
		Rocker_Data.s1  = ((Rocker_Data.buffer[5] >> 4)& 0x000C) >> 2;
		Rocker_Data.s2  = ((Rocker_Data.buffer[5] >> 4)& 0x0003);
		
		Rocker_Data.ch0 -= ((uint16_t)1024);
		Rocker_Data.ch1 -= ((uint16_t)1024);
		Rocker_Data.ch2 -= ((uint16_t)1024);
		Rocker_Data.ch3 -= ((uint16_t)1024);
		Rocker_Data.ch4 -= ((uint16_t)1024);
	}
}

/******************************************************************
  * @ 函数名  ： Remote_Control_Write_Data
  * @ 功能说明： 写入虚拟遥控器信号
  * @ 参数    ： 虚拟遥控器通道信号数据，虚拟遥控无ch4通道
  * @ 返回值  ： NULL
  *****************************************************************/
void Rocker_Write_Data(int s1, int s2, float ch0, float ch1, float ch2, float ch3)
{
	Rocker_Data.s1  = s1;
	Rocker_Data.s2  = s2;
	Rocker_Data.ch0 = ch0;
	Rocker_Data.ch1 = ch1;
	Rocker_Data.ch2 = ch2;
	Rocker_Data.ch3 = ch3;
	
	//计算实际的控制量
	
}

/******************************************************************
  * @ 函数名  ： Rocker_Usb_Callback
  * @ 功能说明： 串口回调函数
  * @ 参数    ： int rate 波特率
  * @ 参数    ： 虚拟遥控器通道信号数据，虚拟遥控无ch4通道
  * @ 返回值  ： NULL
  *****************************************************************/
void Rocker_Usb_Callback(char *type, int rate, int s1, int s2, float ch0, float ch1, float ch2, float ch3)
{
	if(memcmp(type, "rocker-control-data", 19) == 0)
	{
		Usb_Write_Data("{\"type\":\"rocker-control-data\",\"s1\":%d,\"s2\":%d,\"ch0\":%0.3f,\"ch1\":%0.3f,\"ch2\":%0.3f,\"ch3\":%0.3f,\"ch4\":%0.3f}\r\n", \
		Rocker_Data.s1, Rocker_Data.s2, Rocker_Data.ch0, Rocker_Data.ch1, Rocker_Data.ch2, Rocker_Data.ch3, Rocker_Data.ch4);
	}
	if(memcmp(type, "rocker-control-write", 20) == 0)
	{
		Rocker_Write_Data(s1, s2, ch0, ch1, ch2, ch3);
	}
	if(memcmp(type, "rocker-control-rate", 19) == 0){
		Rocker_Init(rate);
	}
}
